﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DataTransferObject.DiaryAndTrackingTask.SupportClassForUpdateTask;
using System.Data;


namespace DataTransferObject.DiaryAndTrackingTask
{
    namespace SupportClassForUpdateTask
    {
        #region Public Support Class
        //[Serializable]
        //public class TaskDayItem
        //{
        //    #region Attributes

        //    private DateTime theDay;
        //    private List<TaskWorked> listTaskWorked = new List<TaskWorked>();
        //    #endregion

        //    #region Constructors

        //    #endregion

        //    #region Properties
        //    public DateTime TheDay
        //    {
        //        get { return this.theDay; }
        //        set { this.theDay = value; }
        //    }

        //    public List<TaskWorked> ListTaskWorked
        //    {
        //        get { return this.listTaskWorked; }
        //        set { this.listTaskWorked = value; }
        //    }


        //    #endregion

        //    #region Methods

        //    #endregion
        //}

        [Serializable]
        public class PiechartItem
        {
            public PiechartItem(Double y, String x)
            {
                xVal = x;
                yVal = y;
            }
            public Double yVal { get; set; }
            public String xVal { get; set; }

            
        }

        [Serializable]
        public class JskeSerie
        {

            #region Constructors
            public JskeSerie()
            {
                this.allPoints = new List<JskePoint>();
            }
            public JskeSerie(String name)
            {
                this.SerieName = name;
                this.allPoints = new List<JskePoint>();
            }
            public JskeSerie(String name, List<JskePoint> points)
            {
                this.SerieName = name;
                this.allPoints = points;
                this.allPoints = new List<JskePoint>();
            }
            #endregion

            #region Properties
            public String SerieName { get; set; }
            public List<JskePoint> allPoints { get; set; }
            public Double taskCode { get; set; }
            #endregion

        }
        [Serializable]
        public class JskePoint
        {
            public JskePoint(Double x, Double y)
            {
                xVal = x;
                yVal = y;
            }
            public Double xVal { get; set; }
            public Double yVal { get; set; }
        }

        [Serializable]
        public class TaskWorked
        {
            #region Attributes

            private Double taskCode;
            private String taskName;
            private int additionalWork;
            private int remainingTime;
            private DateTime timeStamp;
            private String notes;

            #endregion

            #region Constructors

            #endregion

            #region Properties

            public Double TaskCode
            {
                get { return this.taskCode; }
                set { this.taskCode = value; }
            }

            public String TaskName
            {
                get { return this.taskName; }
                set { this.taskName = value; }
            }

            public int AdditionalWork
            {
                get { return this.additionalWork; }
                set { this.additionalWork = value; }
            }

            public int RemainingTime
            {
                get { return this.remainingTime; }
                set { this.remainingTime = value; }
            }

            public DateTime TimeStamp
            {
                get { return this.timeStamp; }
                set { this.timeStamp = value; }
            }

            public String Notes
            {
                get { return this.notes; }
                set { this.notes = value; }
            }

            #endregion

            #region Methods

            #endregion
        }

        [Serializable]
        public class TaskBurndown
        {
            #region Attributes

            private DateTime theDay;
            private int totalRemainTime;
            private List<BurndownTaskDetail> listBDTaskDetail = new List<BurndownTaskDetail>();

            #endregion

            #region Constructors

            #endregion

            #region Properties

            public DateTime TheDay
            {
                get { return this.theDay; }
                set { this.theDay = value; }
            }

            public int TotalRemainTime
            {
                get { return this.totalRemainTime; }
                set { this.totalRemainTime = value; }
            }

            public List<BurndownTaskDetail> ListBDTaskDetail
            {
                get { return this.listBDTaskDetail; }
                set { this.listBDTaskDetail = value; }
            }



            #endregion

            #region Methods

            #endregion
        }

        [Serializable]
        public class BurndownTaskDetail
        {

            #region Attributes
            private Double taskID;
            private String taskName;
            private int remainTime;
            #endregion

            #region Constructors

            #endregion

            #region Properties

            public Double TaskID
            {
                get { return this.taskID; }
                set { this.taskID = value; }
            }

            public String TaskName
            {
                get { return this.taskName; }
                set { this.taskName = value; }
            }

            public int RemainTime
            {
                get { return this.remainTime; }
                set { this.remainTime = value; }
            }


            #endregion

            #region Methods

            #endregion
        }

        #endregion
    }

    [Serializable]
    public class TrackingTaskDS
    {
        #region Attributes

        private DataTable theDataTBLFromTaskList= new DataTable();
        private List<TaskWorked> listTaskWorked = new List<TaskWorked>();
        private List<TaskBurndown> burndownGraphDataFromTo = new List<TaskBurndown>();
        private DateTime burndownFrom = DateTime.MinValue;
        private DateTime burndownTo = DateTime.MaxValue;

        #endregion

        #region Constructors

        // tao DataTable o day

        #endregion

        #region Properties

        public DataTable TheDataTBLFromTaskList
        {
            get { return this.theDataTBLFromTaskList; }
            set { this.theDataTBLFromTaskList = value; }
        }


        public List<TaskWorked> ListTaskWorked
        {
            get { return this.listTaskWorked; }
            set { this.listTaskWorked = value; }
        }

        public List<TaskBurndown> BurndownGraphDataFromTo
        {
            get { return this.burndownGraphDataFromTo; }
            set { this.burndownGraphDataFromTo = value; }
        }

        #endregion

        #region methods
        public List<TaskWorked> getListTWFromTo(DateTime from, DateTime to)
        {
            List<TaskWorked> result = new List<TaskWorked>();
            for (int i = 0; i < ListTaskWorked.Count; i++)
            {
                if (ListTaskWorked[i].TimeStamp >= from.Date && ListTaskWorked[i].TimeStamp <= to.Date)
                {
                    result.Add(ListTaskWorked[i]);
                }
            }
            return result;
        }

        public void addTaskWorkedToList(List<TaskWorked> listTW)
        {
            listTW.Sort(delegate(TaskWorked tw1, TaskWorked tw2)
            {
                return tw1.TimeStamp.CompareTo(tw2.TimeStamp);
            });

            if (this.ListTaskWorked.Count > 0)
            {
                //replace - remove
                int pivot = -1;
                for (int i = 0; i < this.ListTaskWorked.Count; i++)
                {
                    if (this.ListTaskWorked[i].TimeStamp < listTW[0].TimeStamp)
                    {
                        pivot = i;
                    }
                    else
                    {
                        if (this.ListTaskWorked[i].TimeStamp == listTW[0].TimeStamp)
                        {
                            pivot = i;
                            break;
                        }
                        else
                        {
                            break;
                        }
                    }
                }
                //tim thay roi, bay gio replace thoi
                for (int i = pivot; i < this.ListTaskWorked.Count; i++)
                {
                    for (int j = 0; j < listTW.Count; j++)
                    {
                        if (listTW[j].TimeStamp > this.ListTaskWorked[i].TimeStamp)// da vuot ra khoi partition
                        {
                            break;
                        }
                        else if (this.ListTaskWorked[i].TimeStamp == listTW[j].TimeStamp && this.ListTaskWorked[i].TaskCode == listTW[j].TaskCode)
                        {
                            // tim thay 1 phan tu de replace roi
                            listTW.Remove(listTW[j]);
                            break;
                        }
                    }
                }
            }
            // add new items
            for (int i = 0; i < listTW.Count; i++)
            {
                this.ListTaskWorked.Add(listTW[i]);
            }

            
        }

        public void buildBurndownData(DateTime from, DateTime to)
        {
            this.BurndownGraphDataFromTo = new List<TaskBurndown>();
            this.ListTaskWorked.Sort(delegate(TaskWorked t1, TaskWorked t2)
            {
                return t1.TimeStamp.CompareTo(t2.TimeStamp);
            });
            for (int i = 0; i < this.ListTaskWorked.Count; i++)
            {
                if (this.ListTaskWorked[i].TimeStamp >= from && this.ListTaskWorked[i].TimeStamp <= to)
                {
                    TaskBurndown tbd = new TaskBurndown();
                    tbd.TheDay = this.ListTaskWorked[i].TimeStamp;
                    tbd.TotalRemainTime = 0;

                    #region do trong list de them du lieu vao TaskBurndownItem
                    for (int j = i; j < this.ListTaskWorked.Count; j++)
                    {
                        if (j + 1 == ListTaskWorked.Count)// lkhoi cuoi cung
                        {
                            i = listTaskWorked.Count;
                            tbd.ListBDTaskDetail.Add(createTBDD(this.ListTaskWorked[j]));
                            tbd.TotalRemainTime += this.ListTaskWorked[j].RemainingTime;
                            break;
                        }
                        else if (this.ListTaskWorked[j].TimeStamp != this.ListTaskWorked[j + 1].TimeStamp)//ket thuc khoi o day
                        {
                            i = j;
                            tbd.ListBDTaskDetail.Add(createTBDD(this.ListTaskWorked[j]));
                            tbd.TotalRemainTime += this.ListTaskWorked[j].RemainingTime;
                            break;
                        }
                        else if (this.ListTaskWorked[j].TimeStamp == this.ListTaskWorked[j + 1].TimeStamp)//tiep tuc add du lieu vao khoi
                        {
                            tbd.ListBDTaskDetail.Add(createTBDD(this.ListTaskWorked[j]));
                            tbd.TotalRemainTime += this.ListTaskWorked[j].RemainingTime;
                        }
                    }
                    #endregion

                    BurndownGraphDataFromTo.Add(tbd);
                }
            }
        }

        private BurndownTaskDetail createTBDD(TaskWorked t)
        {
            BurndownTaskDetail result = new BurndownTaskDetail();
            result.TaskName = t.TaskName;
            result.TaskID = t.TaskCode;
            result.RemainTime = t.RemainingTime;
            return result;
        }
        #endregion
    }
}
